/*************************************************************************
 *                                                                       *
 * This file is part of the FreeMAPs distribution.  For full copyright   *
 * information, see COPYRIGHT and COPYING.LESSER.                        *
 *                                                                       *
 * Author:           sqbang                                              *
 * Email:            sqbang@ustc.edu                                     *
 * Date:             2011.10.11                                          *
 *                                                                       *
 *************************************************************************/

//declaration header
#include "COMMON/bdry/DirichletBoundaryCondition.h"

//LIBMESH headers

//COMMON headers
#include "COMMON/equa/PDEEquationEnsembleStrategy.h"
#include "COMMON/equa/EquationDomain.h"
#include "COMMON/info/InfoManager.h"
#include "COMMON/info/CommonInfo.h"
#include "COMMON/tbox/Utilities.h"
#include "COMMON/tbox/InputDatabase.h"
#include "COMMON/tbox/LogMessage.h"



namespace FreeMAPs
{

DirichletBoundaryCondition::DirichletBoundaryCondition (
    const std::string& parent_name,
    const std::string& bc_name,
    const PDEEquationEnsembleStrategy* equation_ensemble):
    Parent (parent_name, bc_name, equation_ensemble),
    d_use_interp_tol (0.1)
   // d_para_flux(0)
{
    //d_para_flux = new gFreeMAPs::ParaFluxBean();
}



DirichletBoundaryCondition::~DirichletBoundaryCondition()
{
    this->clear();
}



void
DirichletBoundaryCondition::clear()
{
//    Utilities::clear_pointer_object (d_para_fb);
}


#if 0
void
DirichletBoundaryCondition::set_para_fb(
        gFreeMAPs::ParaFluxBean* para_fb)
{
    d_para_flux = para_fb;
}



gFreeMAPs::ParaFluxBean*
DirichletBoundaryCondition::get_para_fb()
{
    return d_para_flux;
}
#endif

void
DirichletBoundaryCondition::get_info_for_derived_object_from_input (
    const InputDatabase* db)
{
    this->prepare_for_use (db);

    db->insert_allowable_key ("para_fb");

    db->check_allowable_keys();

#if 0
    /*
     * build para_fb
     */
    {
        d_para_fb = new Function (this->get_full_name(), "para_fb");
        db->check_requisite_key ("para_fb", DataType::UNKNOWN, false, false);
        d_para_fb->get_from_input (
            db,
            "para_fb",
            InfoManager::get_instance()->get_variable_info(),
            InfoManager::get_instance()->get_function_info());
        d_para_fb->attach_region (this->get_equation_ensemble()->get_equation_domain()->get_region());
        d_para_fb->set_used_flag();
    }


    //para_fb
    {
        //db->check_requisite_key ("para_fb", DataType::UNKNOWN, false, false);

        if( db->key_exists("para_fb") )
        {
            if(db->is_double("para_fb"))
            {
                d_para_flux->d_para_flux_type = FreeMAPs::FunctionForm::NUMERIC;

                std::stringstream ss_para_flux;
                ss_para_flux << db->get_double("para_fb");
                d_para_flux->d_para_flux_string = ss_para_flux.str();
            }
            else if(db->is_string("para_fb"))
            {
                d_para_flux->d_para_flux_type = FreeMAPs::FunctionForm::ANALYTIC;
                d_para_flux->d_para_flux_string = db->get_string("para_fb");
            }
            else if(db->is_database("para_fb"))
            {
                d_para_flux->d_para_flux_type = FreeMAPs::FunctionForm::FILE_LIST;

                const InputDatabase* db_para_flux = db->get_database("para_fb");
                if(db_para_flux->key_exists("file_list") && db_para_flux->is_database("file_list"))
                {
                    const InputDatabase* db_file_list = db_para_flux->get_database("file_list");

                    //if(db_file_list->key_exists("file_location") && db_file_list->is_string("file_location"))
                    //{
                    //    d_para_flux->d_file_location = db_file_list->get_string("file_location");
                    //}
                    if(db_file_list->key_exists("file_prefix") && db_file_list->is_string("file_prefix"))
                    {
                        const std::string& file_prefix = db_file_list->get_string("file_prefix");;

                        //d_para_flux->d_file_prefix = db_file_list->get_string("file_prefix");

                        if( file_prefix.empty() )
                        {
                            d_para_flux->d_file_location = InfoManager::get_instance()->get_common_info()->get_proj_directory();
                            d_para_flux->d_file_prefix = "L";
                        }
                        else
                        {
                            int pos = file_prefix.find_last_of("/");
                            if(  pos == -1 )
                            {
                                d_para_flux->d_file_location = file_prefix;
                                d_para_flux->d_file_prefix = "L";
                            }
                            else
                            {
                                const int& pos = file_prefix.find_last_of("/");
                                if(  pos == -1 )
                                {
                                    d_para_flux->d_file_location = file_prefix;
                                    d_para_flux->d_file_prefix = "L";
                                }
                                else
                                {
                                    d_para_flux->d_file_location = file_prefix.substr(0, pos);
                                    if(pos == (file_prefix.size() - 1) )
                                    {
                                        d_para_flux->d_file_prefix = "L";
                                    }
                                    else
                                    {
                                        d_para_flux->d_file_prefix = file_prefix.substr(pos+1);
                                    }
                                    //std::cout << __FILE__ << __LINE__ << " para_flux : d_para_flux->d_file_location = " << d_para_flux->d_file_location << std::endl;
                                    //std::cout << __FILE__ << __LINE__ << " para_flux : d_para_flux->d_file_prefix = " << d_para_flux->d_file_prefix << std::endl;
                                }
                            }
                        }
                    }
                    if(db_file_list->key_exists("file_postfix") && db_file_list->is_string("file_postfix"))
                    {
                        d_para_flux->d_file_postfix = db_file_list->get_string("file_postfix");
                        if(d_para_flux->d_file_postfix.empty() || d_para_flux->d_file_postfix == ".")
                        {
                            d_para_flux->d_file_postfix = "txt";
                        }
                        else if(d_para_flux->d_file_postfix.find_first_of(".") == 0)
                        {
                            d_para_flux->d_file_postfix = d_para_flux->d_file_postfix.erase(0, 1);
                        }
                    }
                    if(db_file_list->key_exists("file_index_start") && db_file_list->is_double("file_index_start"))
                    {
                        d_para_flux->d_file_index_start = db_file_list->get_double("file_index_start");
                    }
                    if(db_file_list->key_exists("file_index_end") && db_file_list->is_double("file_index_end"))
                    {
                        d_para_flux->d_file_index_end = db_file_list->get_double("file_index_end");
                    }
                    if(db_file_list->key_exists("file_index_step") && db_file_list->is_double("file_index_step"))
                    {
                        d_para_flux->d_file_index_step = db_file_list->get_double("file_index_step");
                    }
                    if(db_file_list->key_exists("time_start") && db_file_list->is_double("time_start"))
                    {
                        d_para_flux->d_time_start = db_file_list->get_double("time_start");
                    }
                    if(db_file_list->key_exists("time_end") && db_file_list->is_double("time_end"))
                    {
                        d_para_flux->d_time_end = db_file_list->get_double("time_end");
                    }
                    //std::cout << __FILE__ << __LINE__ << " d_file_location = " << d_para_flux->d_file_location << std::endl;
                    //std::cout << __FILE__ << __LINE__ << " d_file_prefix = " << d_para_flux->d_file_prefix << std::endl;
                    //std::cout << __FILE__ << __LINE__ << " d_file_postfix = " << d_para_flux->d_file_postfix << std::endl;
                    //std::cout << __FILE__ << __LINE__ << " d_file_index_start = " << d_para_flux->d_file_index_start << std::endl;
                    //std::cout << __FILE__ << __LINE__ << " d_file_index_end = " << d_para_flux->d_file_index_end << std::endl;
                    //std::cout << __FILE__ << __LINE__ << " d_file_index_step = " << d_para_flux->d_file_index_step << std::endl;
                    //std::cout << __FILE__ << __LINE__ << " d_time_start = " << d_para_flux->d_time_start << std::endl;
                    //std::cout << __FILE__ << __LINE__ << " d_time_end = " << d_para_flux->d_time_end << std::endl;
                }

            }
        }

    }
#endif
}



std::string
DirichletBoundaryCondition::get_info_from_derived_object() const
{
#if 0
    std::ostringstream os, oss;

    os << "physical_parameters\n{\n";

//    oss << *d_para_fb;
    oss << "para_fb = " << d_para_fb;
    os << LogMessage::get_log_info (oss, ONE_TAB) << '\n';

    os << "}";

    return os.str();



    std::ostringstream os, oss;

    os << "physical_parameters\n{\n";

    const FreeMAPs::FunctionForm& para_flux_type = d_para_flux->d_para_flux_type;

    if( para_flux_type == FreeMAPs::FunctionForm::NUMERIC )
    {
        oss << "para_fb = " << d_para_flux->d_para_flux_string;
    }
    else if(d_para_flux->d_para_flux_type == FreeMAPs::FunctionForm::ANALYTIC)
    {
        oss << "para_fb = \"" << d_para_flux->d_para_flux_string << "\"";
    }
    else if(d_para_flux->d_para_flux_type == FreeMAPs::FunctionForm::FILE_LIST)
    {
        oss << "para_fb\n{\n";
        oss << LogMessage::get_prefix (ONE_TAB) << "file_list\n";
        oss << LogMessage::get_prefix (ONE_TAB) << "{\n";

        //file_prefix
        //oss << LogMessage::get_prefix (TWO_TAB) << "file_location    = " << "\""<< d_para_flux->d_file_location <<"\"" << std::endl;
        //oss << LogMessage::get_prefix (TWO_TAB) << "file_prefix      = " << "\""<< d_para_flux->d_file_prefix <<"\"" << std::endl;

        if(d_para_flux->d_file_prefix.empty())
        {
            d_para_flux->d_file_prefix = "L";
        }
        const std::string& file_prefix = d_para_flux->d_file_location + "/" + d_para_flux->d_file_prefix;

        oss << LogMessage::get_prefix (TWO_TAB) << "file_prefix     = " << "\""<< file_prefix <<"\"" << std::endl;

        if(d_para_flux->d_file_postfix.empty())
        {
            d_para_flux->d_file_postfix = ".txt";
        }
        oss << LogMessage::get_prefix (TWO_TAB) << "file_postfix     = " << "\""<< d_para_flux->d_file_postfix <<"\"" << std::endl;
        oss << LogMessage::get_prefix (TWO_TAB) << "file_index_start = " << d_para_flux->d_file_index_start << std::endl;
        oss << LogMessage::get_prefix (TWO_TAB) << "file_index_end   = " << d_para_flux->d_file_index_end << std::endl;
        oss << LogMessage::get_prefix (TWO_TAB) << "file_index_step  = " << d_para_flux->d_file_index_step << std::endl;
        oss << LogMessage::get_prefix (TWO_TAB) << "time_start       = " << d_para_flux->d_time_start << std::endl;
        oss << LogMessage::get_prefix (TWO_TAB) << "time_end         = " << d_para_flux->d_time_end << std::endl;
        oss << LogMessage::get_prefix (ONE_TAB) << "}\n";
        oss << "}";
    }

    os << LogMessage::get_log_info (oss, ONE_TAB) << '\n';
    os << "}";

    return os.str();
    #endif
}

} // namespace FreeMAPs
